package com.gitee.apanlh.util.algorithm.encrypt.symmetric;

import com.gitee.apanlh.util.algorithm.KeyUtils;
import com.gitee.apanlh.util.algorithm.encrypt.AlgorithmMode;
import com.gitee.apanlh.util.algorithm.encrypt.AlgorithmPadding;

/**
 * 	DESede是Triple DES算法的实现
 * 	<br>DESede算法是对称加密算法，使用密钥长度为192位（24字节）
 * 	<br>DESede可以分为两种模式：ECB模式和CBC模式
 * 	<br>ECB模式是最简单的块密码模式，对每个数据块使用相同的密钥进行加密，容易受到字典攻击的影响，不推荐使用
 * 	<br>CBC模式是加密块链模式，使用前一个密文块作为下一个数据块的加密初始向量，提高了安全性
 * 	<br>默认使用DESede/ECB/PKCS5Padding算法，密钥长度为192位
 * 	<br>使用随机生成的密钥和向量，可以通过构造函数自定义密钥和向量
 *	<br>注意密钥长度必须为192位，如果使用CBC向量必须使用64位长度密钥
 *	
 * 	<p><b>示例：</b></p>
 * 	<pre>
 * 	注意:静态方法会更方便构建
 * 	使用默认的ECB模式和PKCS5填充算法，随机生成192位密钥
 * 	DESede aes1 = new DESede();
 * 	// 使用指定的密钥和初始化向量(iv)，采用默认的CBC模式和PKCS5填充算法，192位密钥，64位向量
 * 	DESede aes2 = new DESede(KeyUtils.generate192(), KeyUtils.generate64());
 *  </pre>
 * 	
 *	@author Pan
 */
public class DESede extends BouncyCastleSymmetricAbstract {
	
    /**
     * 	构造函数-ECB模式加密器
     * 	<br>默认DESede/ECB/PKCS5Padding算法
     * 	<br>随机192位密钥长度
     * 	
     * 	@author Pan
     */
    public DESede() {
        this(KeyUtils.generate192());
    }
    
    /**
     * 	构造函数-ECB模式加密器
     * 	<br>默认DESede/ECB/PKCS5Padding算法
     * 	
     * 	@author Pan
     * 	@param 	key 密钥
     */
    public DESede(byte[] key) {
        super(key, null, SymmetricType.DESEDE);
    }
    
    /**
	 * 	构造函数-ECB模式加密器 
	 *  <br>自定义密钥
	 *  <br>自定义填充方法
	 * 
	 * @author Pan
	 * @param  key              密钥
	 * @param  algorithmPadding 加密填充模式
	 */
    public DESede(byte[] key, AlgorithmPadding algorithmPadding) {
		super(key, null, SymmetricType.DESEDE, AlgorithmMode.ECB, algorithmPadding);
	}
    
    /**
     * 	构造函数-CBC模式加密器
     * 	<br>默认DESede/CBC/PKCS5Padding算法
     * 	<br>自定义密钥 
	 *	<br>自定义向量
     * 
     * 	@author Pan
     * 	@param 	key 密钥
     * 	@param 	iv  初始化向量字节
     */
    public DESede(byte[] key, byte[] iv) {
        super(key, iv, SymmetricType.DESEDE, AlgorithmMode.CBC, AlgorithmPadding.PKCS5);
    }
    
    /**
	 * 	构造函数-CBC模式加密器 
	 *  <br>自定义密钥
	 *  <br>自定义向量 
	 *  <br>自定义填充方法
	 * 
	 * @author Pan
	 * @param  key              密钥
	 * @param  iv               初始化向量
	 * @param  algorithmPadding 加密填充模式
	 */
    public DESede(byte[] key, byte[] iv, AlgorithmPadding algorithmPadding) {
    	super(key, iv, SymmetricType.DESEDE, AlgorithmMode.CBC, algorithmPadding);
	}
    
	/**
	 * 	构造函数-自定义模式加密器
	 *  <br>自定义密钥
	 *  <br>自定义向量 
	 *  <br>自定义加密器模式
	 *  <br>自定义填充方法
	 * 
	 * 	@author Pan
	 * 	@param 	key              密钥
	 * 	@param 	iv               初始化向量
	 * 	@param 	algorithmMode    加密器模式
	 * 	@param 	algorithmPadding 加密填充模式
	 */
	public DESede(byte[] key, byte[] iv, AlgorithmMode algorithmMode, AlgorithmPadding algorithmPadding) {
		super(key, iv, SymmetricType.DESEDE, algorithmMode, algorithmPadding);
	}
	
	/**
	 * 	构建-自定义模式加密器
	 *  <br>自定义密钥
	 *  <br>自定义向量 
	 *  <br>自定义加密器模式
	 *  <br>自定义填充方法
	 * 
	 * 	@author Pan
	 * 	@param 	key              密钥
	 * 	@param 	iv               初始化向量
	 * 	@param 	algorithmMode    加密器模式
	 * 	@param 	algorithmPadding 加密填充模式
	 *  @return DESede
	 */
	public static DESede create(byte[] key, byte[] iv, AlgorithmMode algorithmMode, AlgorithmPadding algorithmPadding) {
		return new DESede(key, iv, algorithmMode, algorithmPadding);
	}
	
	/**
     * 	构建-ECB模式加密器
     * 	<br>默认DESede/ECB/PKCS5Padding算法
     * 	<br>随机192位密钥长度
     * 	
     * 	@author Pan
     *  @return DESede
     */
	public static DESede createEcb() {
		return new DESede();
	}
	
	/**
     * 	构建-ECB模式加密器
     * 	<br>默认DESede/ECB/PKCS5Padding算法
     * 	
     * 	@author Pan
     * 	@param 	key 密钥
     *  @return DESede
     */
	public static DESede createEcb(byte[] key) {
		return new DESede(key);
	}
	
	/**
	 * 	构建-ECB模式加密器 
	 *  <br>自定义密钥
	 *  <br>自定义填充方法
	 * 
	 * @author Pan
	 * @param  key              密钥
	 * @param  algorithmPadding 加密填充模式
	 *  @return DESede
	 */
	public static DESede createEcb(byte[] key, AlgorithmPadding algorithmPadding) {
		return new DESede(key, algorithmPadding);
	}
	
	/**
     * 	构建-CBC模式加密器
     * 	<br>默认DESede/CBC/PKCS5Padding算法
     * 	<br>随机192位密钥 
	 *	<br>随机64位向量密钥长度
     * 
     * 	@author Pan
     *  @return DESede
     */
	public static DESede createCbc() {
		return createCbc(KeyUtils.generate192(), KeyUtils.generate64(), AlgorithmPadding.PKCS5);
	}
	
	/**
     * 	构建-CBC模式加密器
     * 	<br>默认DESede/CBC/PKCS5Padding算法
     * 	<br>自定义密钥 
	 *	<br>随机64位向量密钥长度
     * 
     * 	@author Pan
     * 	@param 	key 密钥
     *  @return DESede
     */
	public static DESede createCbc(byte[] key) {
		return createCbc(key, KeyUtils.generate64(), AlgorithmPadding.PKCS5);
	}
	
	/**
     * 	构建-CBC模式加密器
     * 	<br>默认DESede/CBC/PKCS5Padding算法
     * 	<br>自定义密钥 
	 *	<br>自定义向量密钥长度
     * 
     * 	@author Pan
     * 	@param 	key 密钥
     * 	@param 	iv  初始化向量字节
     *  @return DESede
     */
	public static DESede createCbc(byte[] key, byte[] iv) {
		return createCbc(key, iv, AlgorithmPadding.PKCS5);
	}
	
	/**
	 * 	构建-CBC模式加密器 
	 *  <br>自定义密钥
	 *  <br>自定义向量 
	 *  <br>自定义填充方法
	 * 
	 * @author Pan
	 * @param  key              密钥
	 * @param  iv               初始化向量
	 * @param  algorithmPadding 加密填充模式
	 * @return DESede
	 */
	public static DESede createCbc(byte[] key, byte[] iv, AlgorithmPadding algorithmPadding) {
		return new DESede(key, iv, algorithmPadding);
	}
}
